<?php
namespace app\common\library\wechat;
class WeChatPay {
    private $appId;
    private $mchId;
    private $apiKey;

    public function __construct($appId, $mchId, $apiKey) {
        $this->appId = $appId;
        $this->mchId = $mchId;
        $this->apiKey = $apiKey;
    }

    public function unifiedOrder($params) {
        $params['appid'] = $this->appId;
        $params['mch_id'] = $this->mchId;
        $params['nonce_str'] = $this->generateNonceStr();
        $params['sign'] = $this->generateSign($params);

        $xmlData = $this->arrayToXml($params);
        $responseXml = $this->postXmlCurl($xmlData, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
        $responseArray = $this->xmlToArray($responseXml);

        return $responseArray;
    }

    private function generateNonceStr($length = 32) {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $nonceStr = '';

        for ($i = 0; $i < $length; $i++) {
            $nonceStr .= $characters[rand(0, strlen($characters) - 1)];
        }

        return $nonceStr;
    }

    public function generateSign($params) {
        ksort($params);
        $string = '';

        foreach ($params as $key => $value) {
            if ($value != '' && $key != 'sign') {
                $string .= $key . '=' . $value . '&';
            }
        }

        $string .= 'key=' . $this->apiKey;
        $string = md5($string);

        return strtoupper($string);
    }

    private function arrayToXml($array) {
        $xml = '<xml>';

        foreach ($array as $key => $value) {
            if (is_numeric($value)) {
                $xml .= '<' . $key . '>' . $value . '</' . $key . '>';
            } else {
                $xml .= '<' . $key . '><![CDATA[' . $value . ']]></' . $key . '>';
            }
        }

        $xml .= '</xml>';

        return $xml;
    }

    private function postXmlCurl($xml, $url, $second = 30) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        $data = curl_exec($ch);
        curl_close($ch);

        return $data;
    }

    private function xmlToArray($xml) {
        $array = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $json = json_encode($array);
        $responseArray = json_decode($json, true);

        return $responseArray;
    }
}
